#include <Common/error.h>
#include <Compiler/scope.h>

Scope::Scope(FunctionType type, std::unique_ptr<Scope> enclosing) : type(type), enclosing(std::move(enclosing)), chunk(std::make_unique<Chunk>())
{
	this->scope_depth = this->enclosing ? this->enclosing->scope_depth + 1 : 0;
}

void Scope::beginScope()
{
	++scope_depth;
}

void Scope::endScope()
{
	--scope_depth;

	while (!locals.empty() && locals.back().depth > this->scope_depth)
	{
		chunk->write(OpCode::POP, locals.back().name.line);
		locals.pop_back();
	}
}

void Scope::declareLocal(const Token &name)
{
	// FIXME：我没有做禁止重定义的操作，可能会有问题
	addLocal(name);
}

void Scope::defineLocal()
{
	if (scope_depth == 0)
		return;

	Local &top = locals.back();
	top.defined = true;
	top.depth = scope_depth;
}

void Scope::addLocal(const Token &name)
{
	// TODO
	// 由于我们是单字节指令，因此一个作用域最多256个局部变量
	// 这里应当做越界检查
	locals.emplace_back(name, scope_depth, false);
}

int Scope::resolveLocal(const Token &name)
{
	for (int i = locals.size() - 1; i >= 0; i--)
	{
		if (locals[i].name.lexeme == name.lexeme)
		{
			if (!locals[i].defined)
				throw Error(name, "Cannot initialize a variable using it self");

			return i;
		}
	}

	return -1; // 全局变量
}
